#!/bin/bash

# M>N
#   "M" is a file descriptor, which defaults to 1, if not explicitly set.
#   "N" is a filename.
#   File descriptor "M" is redirect to file "N."
# M>&N
#   "M" is a file descriptor, which defaults to 1, if not set.
#   "N" is another file descriptor.
#   File descriptor "M" is redirect to file descriptor "N."

# stdout: > or 1>
# stderr: 2>
# both: &>
ls -al ~/.bashrc test test2 test3 2> test4 1> test5
ls -al ~/.bashrc test test2 test3 &> test6
rm test4 test5 test6

# Temp Redirection
echo "This is an error" >&2
echo "This is normal output"

# Permanent Redirection
# You can tell the shell to redirect a specific file descriptor for the duration
# of the script by using the exec command.
# backup stderr, stdout
exec 4>&2
exec 3>&1
# begin of our scripts
exec 2>testerr
echo "This is the start of the script"
echo "now redirecting all output to another location"
exec 1>testout
echo "This output should go to the testout file"
echo "but this should go to the testerror file" >&2
# restore stderr, stdout
exec 2>&4
exec 1>&3
# close file descriptors manually
exec 4>&-
exec 3>&-
cat testerr testout
rm testerr testout

# read/write file descriptor
# When the script writes data to the file, it starts where the file pointer is
# located. The read command reads the first line of data, so it left the file
# pointer pointing to the first character in the second line of data. When the
# echo statement outputs data to the file, it places the data at the current
# location of the file pointer, overwriting whatever data was there.
exec 3<>testfile
read line <&3
echo "Read: $line"
echo "This is a test line" >&3
if [ -s testfile ]; then
    rm testfile 
fi

# list file descriptors
lsof -a -p $$ -d 0,1,2
if [ $? != 0 ]; then
   /usr/sbin/lsof -a -p $$ -d 0,1,2
fi

